{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import sys\n",
    "import os\n",
    "import xlrd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "''' Global Parameters for graphs '''\n",
    "fs = 24    # font size\n",
    "ms = 11    # marker size\n",
    "figSize = (9, 5.1)    # figure size, (width, height)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5    # size of the patterns inside bar plots\n",
    "plt.rc('xtick', labelsize=fs)            # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)            # fontsize of the tick labels\n",
    "saveGraphDir = \"../Graphs/\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Asymmetric load/p-store latency - I1\n",
    "file_name = \"../Data/pmem-idiosyncrasies.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet = wb.sheet_by_index(0) # Sheet I1\n",
    "\n",
    "# Collect data from sheet\n",
    "x_data=[]\n",
    "p_mem_load=[]\n",
    "p_mem_store=[]\n",
    "dram_load=[]\n",
    "dram_store=[]\n",
    "i = 2\n",
    "while i < sheet.nrows:\n",
    "    x_data.append(sheet.cell_value(i,0))\n",
    "    p_mem_load.append(sheet.cell_value(i,1))\n",
    "    p_mem_store.append(sheet.cell_value(i,2))\n",
    "    dram_load.append(sheet.cell_value(i,3))\n",
    "    dram_store.append(sheet.cell_value(i,4))\n",
    "    i += 1\n",
    "    \n",
    "# Graph for I1\n",
    "plt.ylabel(\"Latency (ns)\", fontsize=fs)\n",
    "plt.xlabel(\"LLC Hit Ratio\", fontsize=fs)\n",
    "plt.xticks(np.arange(min(x_data), max(x_data)+1, 0.2))\n",
    "plt.yticks(np.arange(0, max(p_mem_store)+5, 500))\n",
    "plt.ylim(0, 2600)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.plot(x_data, p_mem_load, 's-c', linewidth=4.0, markersize=ms, label=\"PMEM Load\")\n",
    "plt.plot(x_data, p_mem_store, 'x-y', linewidth=4.0, markersize=ms, label=\"PMEM P-Store\")\n",
    "plt.plot(x_data, dram_load, 'o-m', linewidth=4.0, markersize=ms, label=\"DRAM Load\")\n",
    "plt.plot(x_data, dram_store, '^-g', linewidth=4.0, markersize=ms, label=\"DRAM P-Store\")\n",
    "plt.grid(color='grey', linewidth=0.7, linestyle=':')\n",
    "plt.legend(loc='center', bbox_to_anchor=(0.8,0.53), labelspacing=0.1, frameon=False, fontsize=fs,\n",
    "           handletextpad=0.1, handlelength=1.25)\n",
    "plt.show()\n",
    "#plt.savefig(saveGraphDir + \"i1.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "# Asymmetric PMEM load/p-store bandwidth - I2\n",
    "# Sheet I2\n",
    "file_name = \"../Data/pmem-idiosyncrasies.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet1 = wb.sheet_by_index(1)\n",
    "\n",
    "# Collect data from sheet\n",
    "io_size = []\n",
    "pmem_load = []\n",
    "pmem_store_clwb = []\n",
    "pmem_nt_store = []\n",
    "dram_load = []\n",
    "dram_store_clwb = []\n",
    "dram_nt_store = []\n",
    "i = 3\n",
    "while i < sheet1.ncols:\n",
    "    io_size.append(int(sheet1.cell_value(2,i)))\n",
    "    pmem_load.append(sheet1.cell_value(3,i))\n",
    "    pmem_store_clwb.append(sheet1.cell_value(4,i))\n",
    "    pmem_nt_store.append(sheet1.cell_value(5,i))\n",
    "    dram_load.append(sheet1.cell_value(6,i))\n",
    "    dram_store_clwb.append(sheet1.cell_value(7,i))\n",
    "    dram_nt_store.append(sheet1.cell_value(8,i))\n",
    "    i += 1\n",
    "x = [1,2,3,4,5,6,7]    # X-axis\n",
    "\n",
    "# Graph for PMEM in I2\n",
    "plt.ylabel(\"Bandwidth (GB/s)\", fontsize=fs)\n",
    "plt.xlabel(\"IO Size (bytes)\", fontsize=fs)\n",
    "plt.xticks(x,io_size)\n",
    "plt.yticks(np.arange(0, max(pmem_load)+7, 5))\n",
    "plt.ylim(0, 35)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.plot(x, pmem_load, 's-c', linewidth=4.0, markersize=ms, label=\"load\")\n",
    "plt.plot(x, pmem_store_clwb, 'x-y', linewidth=4.0, markersize=ms, label=\"store + clwb\")\n",
    "plt.plot(x, pmem_nt_store, '^-g', linewidth=4.0, markersize=ms, label=\"nt-store\")\n",
    "plt.grid(color='grey', linewidth=0.7, linestyle=':')\n",
    "plt.legend(bbox_to_anchor=(-0.02, 0.92, 1, .11), loc='upper center',\n",
    "           ncol=3, mode=\"expand\", frameon=False, fontsize=fs, handlelength=1.5, handletextpad=0.25)\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"i2_pmem.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Asymmetric DRAM load/p-store bandwidth - I2\n",
    "plt.ylabel(\"Bandwidth (GB/s)\", fontsize=fs)\n",
    "plt.xlabel(\"IO Size (bytes)\", fontsize=fs)\n",
    "plt.xticks(x,io_size)\n",
    "plt.ylim(0, 80)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.plot(x, dram_load, 's-c', linewidth=4.0, markersize=ms, label=\"load\")\n",
    "plt.plot(x, dram_store_clwb, 'x-y', linewidth=4.0, markersize=ms, label=\"store + clwb\")\n",
    "plt.plot(x, dram_nt_store, '^-g', linewidth=4.0, markersize=ms, label=\"nt-store\")\n",
    "plt.grid(color='grey', linewidth=0.7, linestyle=':')\n",
    "plt.legend(loc='upper left', frameon=False, fontsize=fs, handlelength=1.5, handletextpad=0.5)\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"i2_dram.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Poor bandwidth for small-sized random IO (PMEM Write Bandwidth) - I3\n",
    "# Sheet I3\n",
    "file_name = \"../Data/pmem-idiosyncrasies.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet2 = wb.sheet_by_index(2)\n",
    "\n",
    "# Collect data from sheet\n",
    "io_size_i3 = []\n",
    "bw_seqW = []\n",
    "bw_randW = []\n",
    "ewr_seqW = []\n",
    "ewr_randW = []\n",
    "i = 1\n",
    "while i < sheet2.ncols:\n",
    "    io_size_i3.append(int(sheet2.cell_value(2,i)))\n",
    "    bw_seqW.append(sheet2.cell_value(3,i)/1024)    # Convert from MB to GB\n",
    "    bw_randW.append(sheet2.cell_value(4,i)/1024)\n",
    "    ewr_seqW.append(sheet2.cell_value(9,i))\n",
    "    ewr_randW.append(sheet2.cell_value(10,i))\n",
    "    i += 1\n",
    "x_i3 = [1,2,3,4]    # X-axis\n",
    "\n",
    "# Graph for bandwidth in I3\n",
    "plt.ylabel(\"Bandwidth (GB/s)\", fontsize=fs+4)\n",
    "plt.xlabel(\"IO Size (bytes)\", fontsize=fs+4)\n",
    "plt.xticks(x_i3,io_size)\n",
    "plt.ylim(0, 8)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.rc('xtick', labelsize=fs+4)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs+4)    # fontsize of the tick labels\n",
    "plt.plot(x_i3, bw_seqW, 'x-y', linewidth=4.0, markersize=ms+4, label=\"Seq\")\n",
    "plt.plot(x_i3, bw_randW, '^-g', linewidth=4.0, markersize=ms+4, label=\"Rand\")\n",
    "plt.grid(color='grey', linewidth=0.7, linestyle=':')\n",
    "plt.legend(loc='lower right', frameon=False, fontsize=fs)\n",
    "\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"i3_bw.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# # Poor bandwidth for small-sized random IO (PMEM EWR) - I3\n",
    "plt.ylabel(\"EWR\", fontsize=fs+4)\n",
    "plt.xlabel(\"IO Size (bytes)\", fontsize=fs+4)\n",
    "plt.xticks(x_i3,io_size)\n",
    "plt.yticks(np.arange(0, 1.3, 0.2))\n",
    "plt.ylim(0, 1.2)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.rc('xtick', labelsize=fs+4)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs+4)    # fontsize of the tick labels\n",
    "plt.plot(x_i3, ewr_seqW, 'x-y', linewidth=4.0, markersize=ms+4, label=\"Seq\")\n",
    "plt.plot(x_i3, ewr_randW, '^-g', linewidth=4.0, markersize=ms+4, label=\"Rand\")\n",
    "plt.grid(color='grey', linewidth=0.7, linestyle=':')\n",
    "plt.legend(loc='lower right', frameon=False, fontsize=fs)\n",
    "\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"i3_ewr.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Poor p-store bandwidth on remote NUMA PMEM - I4\n",
    "file_name = \"../Data/pmem-idiosyncrasies.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet3 = wb.sheet_by_index(3)\n",
    "\n",
    "# Collect data for heatmaps\n",
    "threads = []\n",
    "io_size_i4 = []\n",
    "i = 4\n",
    "while i < 10:\n",
    "    threads.append(int(sheet3.cell_value(i,0)))\n",
    "    i += 1\n",
    "\n",
    "i = 1\n",
    "while i < 8:\n",
    "    io_size_i4.append(int(sheet3.cell_value(3,i)))\n",
    "    i += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function to lighten/darken colors inside a colormap\n",
    "import matplotlib\n",
    "def cmap_map(function, cmap):\n",
    "    \"\"\" Applies function (which should operate on vectors of shape 3: [r, g, b]), on colormap cmap.\n",
    "    This routine will break any discontinuous points in a colormap.\n",
    "    \"\"\"\n",
    "    cdict = cmap._segmentdata\n",
    "    step_dict = {}\n",
    "    # First get the list of points where the segments start or end\n",
    "    for key in ('red', 'green', 'blue'):\n",
    "        step_dict[key] = list(map(lambda x: x[0], cdict[key]))\n",
    "    step_list = sum(step_dict.values(), [])\n",
    "    step_list = np.array(list(set(step_list)))\n",
    "    # Then compute the LUT, and apply the function to the LUT\n",
    "    reduced_cmap = lambda step : np.array(cmap(step)[0:3])\n",
    "    old_LUT = np.array(list(map(reduced_cmap, step_list)))\n",
    "    new_LUT = np.array(list(map(function, old_LUT)))\n",
    "    # Now try to make a minimal segment definition of the new LUT\n",
    "    cdict = {}\n",
    "    for i, key in enumerate(['red','green','blue']):\n",
    "        this_cdict = {}\n",
    "        for j, step in enumerate(step_list):\n",
    "            if step in step_dict[key]:\n",
    "                this_cdict[step] = new_LUT[j, i]\n",
    "            elif new_LUT[j,i] != old_LUT[j, i]:\n",
    "                this_cdict[step] = new_LUT[j, i]\n",
    "        colorvector = list(map(lambda x: x + (x[1], ), this_cdict.items()))\n",
    "        colorvector.sort()\n",
    "        cdict[key] = colorvector\n",
    "\n",
    "    return matplotlib.colors.LinearSegmentedColormap('colormap',cdict,1024)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "l and m are the index of the starting cell of the respective heatmap in 'sheet'.\n",
    "'fig_name' if left empty displays the plot else saves it in 'saveGraphDir' path.\n",
    "\"\"\"\n",
    "def heatmap(sheet, l, m, fig_name=None):\n",
    "    data = []\n",
    "    i = l\n",
    "    j = m\n",
    "    while (i < sheet.nrows) and sheet.cell_value(i,j) != \"\":\n",
    "        temp = []\n",
    "        while (j < sheet.ncols) and sheet.cell_value(i,j) != \"\":\n",
    "            temp.append(sheet.cell_value(i,j))\n",
    "            j += 1\n",
    "        data.append(temp)\n",
    "        i += 1\n",
    "        j = m\n",
    "\n",
    "    fig, ax = plt.subplots()\n",
    "    light_red = cmap_map(lambda x: x*0.95 , matplotlib.cm.get_cmap('GnBu')) \n",
    "\n",
    "    # vmin and vmax make all heat maps absolute instead of relative\n",
    "    im = ax.imshow(data, cmap=light_red, aspect='auto', vmin=-25, vmax=100)\n",
    "\n",
    "    # We want to show all ticks...\n",
    "    ax.set_xticks(np.arange(len(io_size_i4)))\n",
    "    ax.set_yticks(np.arange(len(threads)))\n",
    "    # ... and label them with the respective list entries\n",
    "    plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "    plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "    ax.set_xticklabels(io_size_i4)\n",
    "    ax.set_yticklabels(threads)\n",
    "    plt.xlabel(\"IO Size (bytes)\", fontsize=fs+4)\n",
    "    plt.ylabel(\"Threads\", fontsize=fs+4)\n",
    "\n",
    "    # Loop over data dimensions and create text annotations.\n",
    "    for i in range(len(threads)):\n",
    "        for j in range(len(io_size_i4)):\n",
    "            text = ax.text(j, i, round(data[i][j],1),\n",
    "                           ha=\"center\", va=\"center\", color=\"k\", fontsize=fs)\n",
    "\n",
    "    fig.tight_layout()\n",
    "    if fig_name == None:\n",
    "        plt.show()\n",
    "    else:\n",
    "        plt.savefig(saveGraphDir + fig_name + \".pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# I4 heatmap PMEM SeqW\n",
    "\n",
    "# Arguments '4' and '1' are the index of the starting cell for this heatmap\n",
    "#heatmap(sheet3, 4, 1)\n",
    "\n",
    "# To save the figure, pass the filename as the 4th argument to the function\n",
    "heatmap(sheet3, 4, 1, \"i4_pmem_seqw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# I4 heatmap PMEM randW\n",
    "\n",
    "# Arguments '14' and '1' are the index of the starting cell for this heatmap\n",
    "#heatmap(sheet3, 14, 1)\n",
    "\n",
    "# To save the figure, pass the filename as the 4th argument to the function\n",
    "heatmap(sheet3, 14, 1, \"i4_pmem_randw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# I4 heatmap DRAM SeqW\n",
    "\n",
    "# Arguments '4' and '11' are the index of the starting cell for this heatmap\n",
    "#heatmap(sheet3, 4, 11)\n",
    "\n",
    "# To save the figure, pass the filename as the 4th argument to the function\n",
    "heatmap(sheet3, 4,11, \"i4_dram_seqw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# I4 heatmap DRAM RandW\n",
    "\n",
    "# Arguments '14' and '11' are the index of the starting cell for this heatmap\n",
    "#heatmap(sheet3, 14, 11)\n",
    "\n",
    "# To save the figure, pass the filename as the 4th argument to the function\n",
    "heatmap(sheet3, 14,11, \"i4_dram_randw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Store bandwidth lower than p-store bandwidth - I5\n",
    "file_name = \"../Data/pmem-idiosyncrasies.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name)\n",
    "sheet4 = wb.sheet_by_index(4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#I5 heatmap PMEM SeqW store\n",
    "#heatmap(sheet4, 4, 1)\n",
    "heatmap(sheet4, 4, 1, \"i5_pmem_seqw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#I5 heatmap PMEM RandW store\n",
    "#heatmap(sheet4, 14, 1)\n",
    "heatmap(sheet4, 14, 1, \"i5_pmem_randw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#I5 heatmap DRAM SeqW store\n",
    "#heatmap(sheet4, 4, 11)\n",
    "heatmap(sheet4, 4, 11, \"i5_dram_seqw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#I5 heatmap DRAM RandW store\n",
    "#heatmap(sheet4, 14, 11)\n",
    "heatmap(sheet4, 14, 11, \"i5_dram_randw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Sequential IO faster than random IO - I6\n",
    "# Sheet I6\n",
    "file_name = \"../Data/pmem-idiosyncrasies.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet5 = wb.sheet_by_index(5)\n",
    "\n",
    "# Collect data from sheet\n",
    "io_size_i6 = []\n",
    "pmem_seqR = []\n",
    "pmem_randR = []\n",
    "dram_seqR = []\n",
    "dram_randR = []\n",
    "i = 1\n",
    "x = [1,2,3,4,5,6,7]\n",
    "while i < sheet5.ncols:\n",
    "    io_size_i6.append(int(sheet5.cell_value(2,i)))\n",
    "    pmem_seqR.append(sheet5.cell_value(3,i)/1024)   # Convert from MB to GB\n",
    "    pmem_randR.append(sheet5.cell_value(4,i)/1024)\n",
    "    dram_seqR.append(sheet5.cell_value(5,i)/1024)\n",
    "    dram_randR.append(sheet5.cell_value(6,i)/1024)\n",
    "    i += 1\n",
    "\n",
    "# Graphs for I6\n",
    "plt.rc('xtick', labelsize=fs+2)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs+2)    # fontsize of the tick labels\n",
    "plt.ylabel(\"Bandwidth (GB/s)\", fontsize=fs+2)\n",
    "plt.xlabel(\"IO Size (bytes)\", fontsize=fs+2)\n",
    "plt.xticks(x,io_size_i6)\n",
    "plt.ylim(0, 80)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.plot(x, pmem_seqR, 's-c', linewidth=4.0, markersize=ms+2, label=\"PMEM Seq\")\n",
    "plt.plot(x, pmem_randR, 'x-y', linewidth=4.0, markersize=ms+2, label=\"PMEM Rand\")\n",
    "plt.plot(x, dram_seqR, 'o-m', linewidth=4.0, markersize=ms+2, label=\"DRAM Seq\")\n",
    "plt.plot(x, dram_randR, '^-g', linewidth=4.0, markersize=ms+2, label=\"DRAM Rand\")\n",
    "plt.grid(color='grey', linewidth=0.7, linestyle=':')\n",
    "plt.legend(bbox_to_anchor=(0.0, 0.9, 0.9, .11), loc='upper left', frameon=False, fontsize=fs)\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"i6_bw.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#I6 Read Hit Ratio (Bar graph)\n",
    "# Collect data from sheet\n",
    "x_labels = [sheet5.cell_value(9,1), sheet5.cell_value(9,2)]\n",
    "xp_buf_read_hit_ratio = [sheet5.cell_value(10,1), sheet5.cell_value(10,2)]\n",
    "\n",
    "# Plot\n",
    "plt.yticks(np.arange(0, 1.1, 0.2))\n",
    "plt.ylim(0,1.1)\n",
    "plt.margins(x=0.3)\n",
    "plt.ylabel(\"XPBuffer Read Hit Ratio\", fontsize=fs-9)\n",
    "plt.rcParams[\"figure.figsize\"] = (2, 2.8)\n",
    "plt.rc('xtick', labelsize=fs-8)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs-8)     # fontsize of the tick labels\n",
    "plt.bar([1,2], xp_buf_read_hit_ratio, tick_label = x_labels, width=0.3)\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"i6_rhr.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# P-stores are read-modify-write transactions - I7\n",
    "file_name = \"../Data/pmem-idiosyncrasies.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet6 = wb.sheet_by_index(6)\n",
    "\n",
    "# Collect data from sheet\n",
    "x_labels = [sheet6.cell_value(12,0), sheet6.cell_value(13,0)]\n",
    "y_values = [sheet6.cell_value(12,1), sheet6.cell_value(13,1)]\n",
    "\n",
    "# Plot\n",
    "plt.yticks(np.arange(0, 1.1, 0.2))\n",
    "plt.ylim(0,1.1)\n",
    "plt.margins(x=0.3)\n",
    "plt.rcParams[\"figure.figsize\"] = (2, 2.8)\n",
    "plt.rc('xtick', labelsize=fs-8)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs-8)    # fontsize of the tick labels\n",
    "plt.bar([1,2], y_values, tick_label = x_labels, width=0.3)\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"i7.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "''' Functions to set color and pattern to each bar in bar plot '''\n",
    "def setHatch_both(barList, color):\n",
    "    for bar in barList:\n",
    "        bar.set_hatch('//')\n",
    "        bar.set_edgecolor(color)\n",
    "\n",
    "def setHatch_none(barList, color):\n",
    "    for bar in barList:\n",
    "        bar.set_hatch('\\\\')\n",
    "        bar.set_edgecolor(color)\n",
    "\n",
    "def setHatch_index(barList, color):\n",
    "    for bar in barList:\n",
    "        bar.set_hatch('x')\n",
    "        bar.set_edgecolor(color)\n",
    "    \n",
    "def setHatch_recordStore(barList, color):\n",
    "    for bar in barList:\n",
    "        bar.set_hatch('-')\n",
    "        bar.set_edgecolor(color)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "''' Numa-Study graphs '''\n",
    "# Evaluation of MongoDB PMEM Storage Engine with YCSB\n",
    "# Throughput (Sheet 0)\n",
    "file_name = \"../Data/numa-study.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet = wb.sheet_by_index(0)\n",
    "\n",
    "temp = []        # Stores all the values in order in the bar garph\n",
    "case_both =[]    # Stores values for type 'both'\n",
    "case_none = []\n",
    "case_index = []\n",
    "case_recordStore = []\n",
    "i = 0\n",
    "while i < 4:\n",
    "    temp.append(sheet.cell_value(3,i) / 1000)   # Dividing by 1000 to convert to Kops\n",
    "    i+=1\n",
    "while i < 8:\n",
    "    temp.append(sheet.cell_value(3,i) / 1000)\n",
    "    i+=1\n",
    "while i < 12:\n",
    "    temp.append(sheet.cell_value(3,i) / 1000)\n",
    "    i+=1\n",
    "\n",
    "# Extract each case values separately\n",
    "case_both.append(temp[0])\n",
    "case_both.append(temp[4])\n",
    "case_both.append(temp[8])\n",
    "case_index.append(temp[1])\n",
    "case_index.append(temp[5])\n",
    "case_index.append(temp[9])\n",
    "case_recordStore.append(temp[2])\n",
    "case_recordStore.append(temp[6])\n",
    "case_recordStore.append(temp[10])\n",
    "case_none.append(temp[3])\n",
    "case_none.append(temp[7])\n",
    "case_none.append(temp[11])\n",
    "\n",
    "x = [0, 0.5, 1, 1.5, 2.5, 3, 3.5, 4, 5, 5.5, 6, 6.5]    # X-axis for the entire graph\n",
    "x1 = [0, 2.5, 5]      # X-axis for case_both\n",
    "x2 = [0.5, 3, 5.5]    # X-axis for case_recordStore\n",
    "x3 = [1, 3.5, 6]      # X-axis for case_index\n",
    "x4 = [1.5, 4, 6.5]    # X-axis for case_none\n",
    "\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.ylabel(\"Throughput (Kops/s)\", fontsize=fs)\n",
    "plt.xticks([0.75, 3.25, 5.75], ('Workload A', 'Workload B', 'Workload C'))\n",
    "plt.yticks(np.arange(0, max(case_both), 50))\n",
    "ax = plt.axes()\n",
    "ax.xaxis.set_ticks_position('none')\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "\n",
    "barlist = plt.bar(x1, case_both, width= 0.5, fill=False, label='both')\n",
    "# set hatch settings for 4 case/types\n",
    "setHatch_both(barlist, 'r')\n",
    "\n",
    "barlist = plt.bar(x2, case_recordStore, width= 0.5, fill=False, label='record store')\n",
    "setHatch_recordStore(barlist, 'g')\n",
    "\n",
    "barlist = plt.bar(x3, case_index, width= 0.5, fill=False, label='index')\n",
    "setHatch_index(barlist, 'b')\n",
    "\n",
    "barlist = plt.bar(x4, case_none, width= 0.5, fill=False, label='none')\n",
    "setHatch_none(barlist, 'tab:orange')\n",
    "\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"mongodb_ycsb_throughput.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# MongoDB YCSB Drilldown - PMEM Metrics (sheet0)\n",
    "# Collect data from sheet\n",
    "record_store = [sheet.cell_value(7,2), sheet.cell_value(8,2)]\n",
    "index = [sheet.cell_value(7,1), sheet.cell_value(8,1)]\n",
    "\n",
    "# Plot\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.yticks(np.arange(0, 1.1, 0.2))\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "plt.ylim(0,1.1)\n",
    "plt.margins(x=0.3)\n",
    "plt.xticks([0.5, 3.5], ('EWR', 'EBR'))\n",
    "plt.xlabel(\"Metric\", fontsize=fs)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.bar([0,3], record_store, fill=False, hatch='-', edgecolor='green', label='record store')\n",
    "plt.bar([1,4], index, fill=False, hatch='x', edgecolor='blue', label='index')\n",
    "plt.legend(frameon=False, fontsize=fs, handleheight=1.3, loc='upper left', ncol=2, handletextpad=0.5)\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"mongodb_ycsb_counters.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# MongoDB YCSB Drilldown - Store Histogram (sheet0)\n",
    "# Collect data\n",
    "labels = []\n",
    "index = []\n",
    "recordStore = []\n",
    "i = 12\n",
    "while i < 21:\n",
    "    if (not(i==13 or i==14 or i == 18 or i == 19)):  # Remove these four labels as no value in graph\n",
    "        labels.append(str(sheet.cell_value(i, 0)))\n",
    "        index.append(sheet.cell_value(i, 1))\n",
    "        recordStore.append(sheet.cell_value(i, 2))\n",
    "    i += 1\n",
    "\n",
    "# x-axis for index\n",
    "x1 = np.arange(0, 21, 5)\n",
    "# x-axis for record store\n",
    "x2 = np.arange(1, 22, 5)\n",
    "\n",
    "plt.rc('xtick', labelsize=fs-3)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)      # fontsize of the tick labels\n",
    "plt.yticks(np.arange(0, 100, 10))\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "plt.xticks(np.arange(0.5, 22, 5), labels)\n",
    "plt.ylabel(\"% of Total Data\", fontsize=fs)\n",
    "plt.xlabel(\"Store Size Range\", fontsize=fs)\n",
    "plt.bar(x1, recordStore, fill=False, hatch='-', edgecolor='green', label='record store')\n",
    "plt.bar(x2, index, fill=False, hatch='x', edgecolor='blue', label='index')\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"mongodb_ycsb_store_histogram.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 'step' represents the step size of y-axis. If 'fileName' is passed, then graph is saved\n",
    "def plot_lat_numa_study(sheet, y_lim=250, step=50, fileName=\"\", noLegend=True):\n",
    "    # Collect data\n",
    "    labels = []\n",
    "    case_both =[]\n",
    "    j = 0\n",
    "    while j < sheet.ncols:\n",
    "        labels.append(sheet.cell_value(1,j))\n",
    "        case_both.append(sheet.cell_value(3,j))\n",
    "        j += 4\n",
    "\n",
    "    case_none = []\n",
    "    case_index = []\n",
    "    case_recordStore = []\n",
    "    j = 1\n",
    "    while j < sheet.ncols:\n",
    "        case_index.append(sheet.cell_value(3,j))\n",
    "        j += 4\n",
    "    j = 2\n",
    "    while j < sheet.ncols:\n",
    "        case_recordStore.append(sheet.cell_value(3,j))\n",
    "        j += 4\n",
    "    j = 3\n",
    "    while j < sheet.ncols:\n",
    "        case_none.append(sheet.cell_value(3,j))\n",
    "        j += 4\n",
    "\n",
    "    temp=[]\n",
    "    j = 0\n",
    "    while j < sheet.ncols:\n",
    "        temp.append(sheet.cell_value(3,j))\n",
    "        j += 1\n",
    "\n",
    "    # X-axis for each case/type\n",
    "    x1 = np.arange(0, 11, 2.5)\n",
    "    x2 = np.arange(0.5, 11.5, 2.5)\n",
    "    x3 = np.arange(1, 12, 2.5)\n",
    "    x4 = np.arange(1.5, 12.5, 2.5)\n",
    "    # Combined X-axis for all types\n",
    "    x = []\n",
    "    for e in x1:\n",
    "        x.append(e)\n",
    "    for e in x2:\n",
    "        x.append(e)\n",
    "    for e in x3:\n",
    "        x.append(e)\n",
    "    for e in x4:\n",
    "        x.append(e)\n",
    "    x.sort()\n",
    "\n",
    "    # Plot graph\n",
    "    plt.rc('xtick', labelsize=fs-2)    # fontsize of the tick labels\n",
    "    plt.rc('ytick', labelsize=fs)      # fontsize of the tick labels\n",
    "    plt.ylabel(\"Latency (us)\", fontsize=fs)\n",
    "    plt.ylim(0, y_lim)\n",
    "    plt.yticks(np.arange(0, y_lim+1, step))\n",
    "    plt.xticks([0.75, 3.25, 5.75, 8.25, 10.75], labels)\n",
    "    plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "\n",
    "    barlist = plt.bar(x1, case_both, width= 0.5, fill=False, label='both')\n",
    "    # set hatch settings for 4 case/types\n",
    "    setHatch_both(barlist, 'r')\n",
    "\n",
    "    barlist = plt.bar(x2, case_recordStore, width= 0.5, fill=False, label='record store')\n",
    "    setHatch_recordStore(barlist, 'g')\n",
    "    \n",
    "    barlist = plt.bar(x3, case_index, width= 0.5, fill=False, label='index')\n",
    "    setHatch_index(barlist, 'b')\n",
    "    \n",
    "    barlist = plt.bar(x4, case_none, width= 0.5, fill=False, label='none')\n",
    "    setHatch_none(barlist, 'tab:orange')\n",
    "\n",
    "    if (not noLegend):\n",
    "        plt.legend(bbox_to_anchor=(0.0, 0.65, 0.9, .11), mode=\"expand\", ncol=2, frameon=False,\n",
    "            fontsize=fs, handleheight=1.3, handletextpad=0.5)\n",
    "\n",
    "    if (fileName == \"\"):\n",
    "        plt.show()\n",
    "    else:\n",
    "        plt.savefig(saveGraphDir + \"/mongodb_ycsb_\" + fileName + \".pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Evaluation of MongoDB PMEM Storage Engine with YCSB - Avg Lat (sheet 1)\n",
    "file_name = \"../Data/numa-study.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name)\n",
    "sheet = wb.sheet_by_index(1)\n",
    "plot_lat_numa_study(wb.sheet_by_index(1), 450, 50, \"avg_lat\", False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Evaluation of MongoDB PMEM Storage Engine with YCSB - P95 Lat (sheet 2)\n",
    "file_name = \"../Data/numa-study.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name)\n",
    "plot_lat_numa_study(wb.sheet_by_index(2), 2000, 500, \"p95_lat\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Evaluation of MongoDB PMEM Storage Engine with YCSB - P99 Lat (sheet 3)\n",
    "file_name = \"../Data/numa-study.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name)\n",
    "plot_lat_numa_study(wb.sheet_by_index(3), 2500, 500, \"p99_lat\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Lock-free Ring Buffer Evaluation - Operation Latency\n",
    "# Rb_queue latency(sheet 0)\n",
    "\n",
    "# Read data\n",
    "file_name=\"../Data/lock-free-results.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet = wb.sheet_by_index(0)\n",
    "\n",
    "labels = []\n",
    "tx_adr = []\n",
    "tx_eadr = []\n",
    "tx_free_eadr = []\n",
    "volatile = []\n",
    "temp = []\n",
    "j = 1\n",
    "while j < sheet.ncols:\n",
    "    labels.append(sheet.cell_value(2,j))\n",
    "    tx_adr.append(sheet.cell_value(3, j))\n",
    "    temp.append(sheet.cell_value(3, j))\n",
    "    tx_eadr.append(sheet.cell_value(4, j))\n",
    "    temp.append(sheet.cell_value(4, j))\n",
    "    tx_free_eadr.append(sheet.cell_value(5, j))\n",
    "    temp.append(sheet.cell_value(5, j))\n",
    "    volatile.append(sheet.cell_value(6, j))\n",
    "    temp.append(sheet.cell_value(6, j))\n",
    "    j += 1\n",
    "labels[1] = \"p99\\npush\"\n",
    "labels[4] = \"p99\\npop\"\n",
    "    \n",
    "# X-axis\n",
    "x1 = np.arange(0, 13, 2.5)\n",
    "x2 = np.arange(0.5, 13.5, 2.5)\n",
    "x3 = np.arange(1, 14, 2.5)\n",
    "x4 = np.arange(1.5, 14.5, 2.5)\n",
    "x = []\n",
    "for e in x1:\n",
    "    x.append(e)\n",
    "for e in x2:\n",
    "    x.append(e)\n",
    "for e in x3:\n",
    "    x.append(e)\n",
    "for e in x4:\n",
    "    x.append(e)\n",
    "x.sort()\n",
    "    \n",
    "# Plot graph\n",
    "plt.rc('xtick', labelsize=fs-2)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)      # fontsize of the tick labels\n",
    "plt.ylabel(\"Latency (us)\", fontsize=fs)\n",
    "plt.ylim(0, 21, 2)\n",
    "plt.yticks(np.arange(0, 21, 4))\n",
    "plt.xticks([0.75, 3.25, 5.75, 8.25, 10.75, 13.25], labels)\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "\n",
    "barlist = plt.bar(x1, tx_adr, width= 0.5, fill=False, label='TX (ADR)')\n",
    "# set hatch settings for 4 case/types\n",
    "setHatch_both(barlist, 'tab:olive')\n",
    "\n",
    "barlist = plt.bar(x2, tx_eadr, width= 0.5, fill=False, label='TX (eADR)')\n",
    "setHatch_none(barlist, 'tab:cyan')\n",
    "\n",
    "barlist = plt.bar(x3, tx_free_eadr, width= 0.5, fill=False, label='TX-free')\n",
    "setHatch_index(barlist, 'tab:purple')\n",
    "\n",
    "barlist = plt.bar(x4, volatile, width= 0.5, fill=False, label='Volatile')\n",
    "setHatch_recordStore(barlist, 'tab:brown')\n",
    "\n",
    "# plot again to make edges of bar black\n",
    "plt.bar(x, temp, color='none', width= 0.5, edgecolor='k')\n",
    "\n",
    "plt.legend(bbox_to_anchor=(-0.025, 0.95, 0.9, .11), loc=\"upper right\", mode=\"expand\", ncol=2, frameon=False,\n",
    "           fontsize=fs, handleheight=1.3, handletextpad=0.1)\n",
    "\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"rb_queue_lat.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lock-free Ring Buffer Evaluation - PMEM Hardware Counters\n",
    "# Hardware counters (sheet 0)\n",
    "\n",
    "# Read data\n",
    "sheet = wb.sheet_by_index(0)\n",
    "labels = []\n",
    "tx_adr = []\n",
    "tx_eadr = []\n",
    "tx_free_eadr = []\n",
    "temp = []\n",
    "j = 1\n",
    "while j < sheet.ncols - 1:\n",
    "    labels.append(sheet.cell_value(16, j))\n",
    "    tx_adr.append(sheet.cell_value(17, j))\n",
    "    temp.append(sheet.cell_value(17, j))\n",
    "    tx_eadr.append(sheet.cell_value(18, j))\n",
    "    temp.append(sheet.cell_value(18, j))\n",
    "    tx_free_eadr.append(sheet.cell_value(19, j))\n",
    "    temp.append(sheet.cell_value(19, j))\n",
    "    j += 1\n",
    "\n",
    "# Make xlabels split in two lines as they are big\n",
    "for i in range(len(labels)):\n",
    "    labels[i] = labels[i].replace(\" \", \"\\n\")\n",
    "\n",
    "# X-axis\n",
    "x1 = np.arange(0, 10.5, 2.5)\n",
    "x2 = np.arange(0.5, 11, 2.5)\n",
    "x3 = np.arange(1, 12, 2.5)\n",
    "x = []\n",
    "for e in x1:\n",
    "    x.append(e)\n",
    "for e in x2:\n",
    "    x.append(e)\n",
    "for e in x3:\n",
    "    x.append(e)\n",
    "x.sort()\n",
    "\n",
    "# Plot graph\n",
    "plt.rc('xtick', labelsize=fs-1)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)      # fontsize of the tick labels\n",
    "plt.ylabel(\"Data Size (GB) / Operations (M)\", fontsize=fs-3)\n",
    "plt.yticks(np.arange(0, 141, 20))\n",
    "plt.ylim(0, 140)\n",
    "plt.xticks([ 0.5, 3.0, 5.5,8.0, 10.5], labels)\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "\n",
    "barlist = plt.bar(x1, tx_adr, width= 0.5, fill=False, label='TX (ADR)')\n",
    "# set hatch settings for 4 case/types\n",
    "setHatch_both(barlist, 'tab:olive')\n",
    "\n",
    "barlist = plt.bar(x2, tx_eadr, width= 0.5, fill=False, label='TX (eADR)')\n",
    "setHatch_none(barlist, 'tab:cyan')\n",
    "\n",
    "barlist = plt.bar(x3, tx_free_eadr, width= 0.5, fill=False, label='TX-free')\n",
    "setHatch_index(barlist, 'tab:purple')\n",
    "\n",
    "# plot again to make edges of bar black\n",
    "plt.bar(x, temp, color='none', width= 0.5, edgecolor='k')\n",
    "\n",
    "plt.legend(loc=\"upper right\", frameon=False, fontsize=fs-1, handleheight=1.3, \n",
    "          handletextpad=0.5)\n",
    "\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"rb_queue_counters.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Effect of flushing data with low temporal locality in eADR mode (sheet 0)\n",
    "\n",
    "# Read data\n",
    "file_name=\"../Data/lock-free-results.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet = wb.sheet_by_index(0)\n",
    "labels = []\n",
    "tx = []\n",
    "tx_free = []\n",
    "temp = []\n",
    "j = 1\n",
    "while j < sheet.ncols:\n",
    "    labels.append(sheet.cell_value(35,j))\n",
    "    tx.append(sheet.cell_value(36, j))\n",
    "    temp.append(sheet.cell_value(36, j))\n",
    "    tx_free.append(sheet.cell_value(37, j))\n",
    "    temp.append(sheet.cell_value(37, j))\n",
    "    j += 1\n",
    "labels[1] = \"p99\\npush\"\n",
    "labels[4] = \"p99\\npop\"\n",
    "\n",
    "# X-axis\n",
    "x1 = np.arange(0, 13, 2.5)\n",
    "x2 = np.arange(0.5, 13.5, 2.5)\n",
    "x = []\n",
    "for e in x1:\n",
    "    x.append(e)\n",
    "for e in x2:\n",
    "    x.append(e)\n",
    "x.sort()\n",
    "\n",
    "# Plot graph\n",
    "plt.rcParams[\"figure.figsize\"] = (9, 2.3)\n",
    "plt.rc('xtick', labelsize=fs-4)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs-5)    # fontsize of the tick labels\n",
    "plt.ylabel(\"Normalized Latency\", fontsize=fs-6)\n",
    "plt.ylim(0, 6)\n",
    "plt.yticks(np.arange(0, 7, 1))\n",
    "plt.xticks([0.25, 2.75, 5.25, 7.75, 10.25, 12.75], labels)\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "\n",
    "barlist = plt.bar(x1, tx, width= 0.5, fill=False, label='TX')\n",
    "setHatch_none(barlist, 'tab:cyan')\n",
    "\n",
    "barlist = plt.bar(x2, tx_free, width= 0.5, fill=False, label='TX-free')\n",
    "setHatch_index(barlist, 'tab:purple')\n",
    "\n",
    "# plot again to make edges of bar black\n",
    "plt.bar(x, temp, color='none', width= 0.5, edgecolor='k')\n",
    "# draw horizontal line for at normalized latency of 1.\n",
    "plt.axhline(y=1, color='k', linestyle='dotted')\n",
    "\n",
    "plt.legend(loc=\"upper left\", frameon=False, fontsize=fs-4, handleheight=1.4, ncol=2,\n",
    "          handletextpad=0.5)\n",
    "\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"rb_queue_no_flush.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lock-free Linkedlist Throughput Evaluation - ADR Design (4096 Range)\n",
    "sheet = wb.sheet_by_index(1)\n",
    "\n",
    "labels = []\n",
    "link_free = []\n",
    "soft = []\n",
    "tlog = []\n",
    "temp = []\n",
    "i = 4\n",
    "while i < 11:\n",
    "    labels.append(int(sheet.cell_value(i, 0)))\n",
    "    link_free.append(sheet.cell_value(i, 1)/(10**6)) # Convert ops to Mops\n",
    "    temp.append(sheet.cell_value(i, 1)/(10**6))\n",
    "    soft.append(sheet.cell_value(i, 2)/(10**6))\n",
    "    temp.append(sheet.cell_value(i, 2)/(10**6))\n",
    "    tlog.append(sheet.cell_value(i, 3)/(10**6))\n",
    "    temp.append(sheet.cell_value(i, 3)/(10**6))\n",
    "    i += 1\n",
    "\n",
    "# X-axis\n",
    "x1 = np.arange(0, 15.5, 2.5)\n",
    "x2 = np.arange(0.5, 16, 2.5)\n",
    "x3 = np.arange(1, 17, 2.5)\n",
    "x = []\n",
    "for e in x1:\n",
    "    x.append(e)\n",
    "for e in x2:\n",
    "    x.append(e)\n",
    "for e in x3:\n",
    "    x.append(e)\n",
    "x.sort()\n",
    "\n",
    "# Plot graph\n",
    "figSize = (9, 5.1)               # figure size, (width, height)\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.ylabel(\"Throughput (Mops/s)\", fontsize=fs)\n",
    "plt.xlabel(\"Update %\", fontsize=fs)\n",
    "plt.xticks([ 0.5, 3.0, 5.5,8.0, 10.5, 13, 15.5], labels)\n",
    "plt.yticks(np.arange(0, 6, 1))\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "\n",
    "barlist = plt.bar(x1, link_free, width= 0.5, fill=False, label='Link-free')\n",
    "# set hatch settings for 4 case/types\n",
    "setHatch_both(barlist, 'violet')\n",
    "\n",
    "barlist = plt.bar(x2, soft, width= 0.5, fill=False, label='SOFT')\n",
    "setHatch_none(barlist, 'tab:gray')\n",
    "\n",
    "barlist = plt.bar(x3, tlog, width= 0.5, fill=False, label='TLog')\n",
    "setHatch_index(barlist, 'teal')\n",
    "\n",
    "# plot again to make edges of bar black\n",
    "plt.bar(x, temp, color='none', width= 0.5, edgecolor='k')\n",
    "\n",
    "plt.legend(loc=\"upper right\", frameon=False, fontsize=fs, handleheight=1.3, \n",
    "           handletextpad=0.2, mode=\"expand\", ncol=3, bbox_to_anchor=(0.12,0.9, 0.9, .11))\n",
    "\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"ll_adr_4096.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lock-free Linkedlist Throughput Evaluation - ADR Design (1024 Range)\n",
    "sheet = wb.sheet_by_index(1)\n",
    "\n",
    "labels = []\n",
    "link_free = []\n",
    "soft = []\n",
    "tlog = []\n",
    "temp = []\n",
    "i = 4\n",
    "while i < 11:\n",
    "    labels.append(int(sheet.cell_value(i, 6)))\n",
    "    link_free.append(sheet.cell_value(i, 7)/(10**6)) # Convert ops to Mops\n",
    "    temp.append(sheet.cell_value(i, 7)/(10**6))\n",
    "    soft.append(sheet.cell_value(i, 8)/(10**6))\n",
    "    temp.append(sheet.cell_value(i, 8)/(10**6))\n",
    "    tlog.append(sheet.cell_value(i, 9)/(10**6))\n",
    "    temp.append(sheet.cell_value(i, 9)/(10**6))\n",
    "    i += 1\n",
    "\n",
    "# X-axis\n",
    "x1 = np.arange(0, 15.5, 2.5)\n",
    "x2 = np.arange(0.5, 16, 2.5)\n",
    "x3 = np.arange(1, 17, 2.5)\n",
    "x = []\n",
    "for e in x1:\n",
    "    x.append(e)\n",
    "for e in x2:\n",
    "    x.append(e)\n",
    "for e in x3:\n",
    "    x.append(e)\n",
    "x.sort()\n",
    "\n",
    "# Plot graph\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.ylabel(\"Throughput (Mops/s)\", fontsize=fs)\n",
    "plt.xlabel(\"Update %\", fontsize=fs+2)\n",
    "plt.xticks([ 0.5, 3.0, 5.5,8.0, 10.5, 13, 15.5], labels)\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "\n",
    "barlist = plt.bar(x1, link_free, width= 0.5, fill=False, label='Link-free')\n",
    "# set hatch settings for 4 case/types\n",
    "setHatch_both(barlist, 'violet')\n",
    "\n",
    "barlist = plt.bar(x2, soft, width= 0.5, fill=False, label='SOFT')\n",
    "setHatch_none(barlist, 'tab:gray')\n",
    "\n",
    "barlist = plt.bar(x3, tlog, width= 0.5, fill=False, label='TLog')\n",
    "setHatch_index(barlist, 'teal')\n",
    "\n",
    "# plot again to make edges of bar black\n",
    "plt.bar(x, temp, color='none', width= 0.5, edgecolor='k')\n",
    "\n",
    "plt.legend(loc=\"upper right\", frameon=False, fontsize=fs, handleheight=1.3,\n",
    "           handletextpad=0.2, mode=\"expand\", ncol=3, bbox_to_anchor=(0.12,0.9, 0.9, .11))\n",
    "\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"ll_adr_1024.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lock-free Linkedlist Throughput Evaluation - ADR Design (256 Range)\n",
    "sheet = wb.sheet_by_index(1)\n",
    "\n",
    "labels = []\n",
    "link_free = []\n",
    "soft = []\n",
    "tlog = []\n",
    "temp = []\n",
    "i = 4\n",
    "while i < 11:\n",
    "    labels.append(int(sheet.cell_value(i, 12)))\n",
    "    link_free.append(sheet.cell_value(i, 13)/(10**6)) # Convert ops to Mops\n",
    "    temp.append(sheet.cell_value(i, 13)/(10**6))\n",
    "    soft.append(sheet.cell_value(i, 14)/(10**6))\n",
    "    temp.append(sheet.cell_value(i, 14)/(10**6))\n",
    "    tlog.append(sheet.cell_value(i, 15)/(10**6))\n",
    "    temp.append(sheet.cell_value(i, 15)/(10**6))\n",
    "    i += 1\n",
    "\n",
    "# X-axis\n",
    "x1 = np.arange(0, 15.5, 2.5)\n",
    "x2 = np.arange(0.5, 16, 2.5)\n",
    "x3 = np.arange(1, 17, 2.5)\n",
    "x = []\n",
    "for e in x1:\n",
    "    x.append(e)\n",
    "for e in x2:\n",
    "    x.append(e)\n",
    "for e in x3:\n",
    "    x.append(e)\n",
    "x.sort()\n",
    "\n",
    "# Plot graph\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.ylabel(\"Throughput (Mops/s)\", fontsize=fs)\n",
    "plt.xlabel(\"Update %\", fontsize=fs+2)\n",
    "plt.xticks([ 0.5, 3.0, 5.5,8.0, 10.5, 13, 15.5], labels)\n",
    "plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "\n",
    "barlist = plt.bar(x1, link_free, width= 0.5, fill=False, label='Link-free')\n",
    "# set hatch settings for 4 case/types\n",
    "setHatch_both(barlist, 'violet')\n",
    "\n",
    "barlist = plt.bar(x2, soft, width= 0.5, fill=False, label='SOFT')\n",
    "setHatch_none(barlist, 'tab:gray')\n",
    "\n",
    "barlist = plt.bar(x3, tlog, width= 0.5, fill=False, label='TLog')\n",
    "setHatch_index(barlist, 'teal')\n",
    "\n",
    "# plot again to make edges of bar black\n",
    "plt.bar(x, temp, color='none', width= 0.5, edgecolor='k')\n",
    "\n",
    "plt.legend(loc=\"upper right\", frameon=False, fontsize=fs, handleheight=1.3,\n",
    "           handletextpad=0.2, mode=\"expand\", ncol=3, bbox_to_anchor=(0.15,0.9, 0.85, .11))\n",
    "\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"ll_adr_256.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "'j' is the column of eadr tables\n",
    "'ymax' maximum limit on y axis for the graph\n",
    "'step' is the step size of y-axis\n",
    "if 'fileName' is passed, then graph is saved\n",
    "'''\n",
    "def eADR_throughput(sheet, j, ymax, step, fileName=\"\"):\n",
    "    labels = []\n",
    "    link_free = []\n",
    "    soft = []\n",
    "    tlog = []\n",
    "    log_free = []\n",
    "    temp = []\n",
    "    i = 28\n",
    "    while i < 35:\n",
    "        labels.append(int(sheet.cell_value(i, j)))\n",
    "        link_free.append(sheet.cell_value(i, j+1)/(10**6)) # Convert ops to Mops\n",
    "        temp.append(sheet.cell_value(i, j+1)/(10**6))\n",
    "        soft.append(sheet.cell_value(i, j+2)/(10**6))\n",
    "        temp.append(sheet.cell_value(i, j+2)/(10**6))\n",
    "        tlog.append(sheet.cell_value(i, j+3)/(10**6))\n",
    "        temp.append(sheet.cell_value(i, j+3)/(10**6))\n",
    "        log_free.append(sheet.cell_value(i, j+4)/(10**6))\n",
    "        temp.append(sheet.cell_value(i, j+4)/(10**6))\n",
    "        i += 1\n",
    "\n",
    "    # X-axis\n",
    "    x1 = np.arange(0, 21, 3)\n",
    "    x2 = np.arange(0.5, 21, 3)\n",
    "    x3 = np.arange(1, 21, 3)\n",
    "    x4 = np.arange(1.5, 21, 3)\n",
    "    x = []\n",
    "    for e in x1:\n",
    "        x.append(e)\n",
    "    for e in x2:\n",
    "        x.append(e)\n",
    "    for e in x3:\n",
    "        x.append(e)\n",
    "    for e in x4:\n",
    "        x.append(e)\n",
    "    x.sort()\n",
    "\n",
    "    # Plot graph\n",
    "    plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "    plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "    plt.ylabel(\"Throughput (Mops/s)\", fontsize=fs)\n",
    "    plt.xlabel(\"Update %\", fontsize=fs)\n",
    "    plt.ylim(0, ymax)\n",
    "    plt.yticks(np.arange(0, ymax+1, step))\n",
    "    plt.xticks([0.75, 3.75, 6.75, 9.75, 12.75, 15.75, 18.75], labels)\n",
    "    plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "\n",
    "    barlist = plt.bar(x1, link_free, width= 0.5, fill=False, label='Link-free')\n",
    "    # set hatch settings for 4 case/types\n",
    "    setHatch_both(barlist, 'violet')\n",
    "\n",
    "    barlist = plt.bar(x2, soft, width= 0.5, fill=False, label='SOFT')\n",
    "    setHatch_none(barlist, 'tab:gray')\n",
    "\n",
    "    barlist = plt.bar(x3, tlog, width= 0.5, fill=False, label='TLog')\n",
    "    setHatch_index(barlist, 'teal')\n",
    "\n",
    "    barlist = plt.bar(x4, log_free, width= 0.5, fill=False, label='Log-free')\n",
    "    setHatch_recordStore(barlist, 'goldenrod')\n",
    "\n",
    "    # plot again to make edges of bar black\n",
    "    plt.bar(x, temp, color='none', width= 0.5, edgecolor='k')\n",
    "\n",
    "    plt.legend(loc=\"upper right\", frameon=False, fontsize=fs, handleheight=1.3, \n",
    "               handletextpad=0.2, mode=\"expand\", ncol=2, bbox_to_anchor=(0.24,0.94, 0.80, .11))\n",
    "\n",
    "    if (fileName == \"\"):\n",
    "        plt.show()\n",
    "    else:\n",
    "        plt.savefig(saveGraphDir + \"ll_eadr_\" + fileName + \".pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lock-free Linkedlist Throughput Evaluation - eADR Design (4096 Range)\n",
    "#eADR_throughput(wb.sheet_by_index(1), 0, 6, 1)\n",
    "eADR_throughput(wb.sheet_by_index(1), 0, 6, 1, \"4096\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lock-free Linkedlist Throughput Evaluation - eADR Design (1024 Range)\n",
    "#eADR_throughput(wb.sheet_by_index(1), 7, 25, 5)\n",
    "eADR_throughput(wb.sheet_by_index(1), 7, 25, 5, \"1024\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lock-free Linkedlist Throughput Evaluation - eADR Design (256 Range)\n",
    "#eADR_throughput(wb.sheet_by_index(1), 14, 160, 25)\n",
    "eADR_throughput(wb.sheet_by_index(1), 14, 160, 25, \"256\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Operation Latency, 50% updates (sheet 1)\n",
    "import matplotlib as mlp\n",
    "\n",
    "def opr_lat_update(sheet, i, y_max, fileName=\"\"):\n",
    "    soft = []\n",
    "    tlog = []\n",
    "    j = 1\n",
    "    i_max = i + 2\n",
    "    k = j+1\n",
    "    while i < i_max:\n",
    "        soft.append(sheet.cell_value(i,j))\n",
    "        soft.append(sheet.cell_value(i,j+2))\n",
    "        soft.append(sheet.cell_value(i,j+4))\n",
    "        tlog.append(sheet.cell_value(i,k))\n",
    "        tlog.append(sheet.cell_value(i,k+2))\n",
    "        tlog.append(sheet.cell_value(i,k+4))\n",
    "        i += 1\n",
    "\n",
    "    temp = []\n",
    "    for i in range(len(soft)):\n",
    "        temp.append(soft[i])\n",
    "        temp.append(tlog[i])\n",
    "\n",
    "    #X-axis\n",
    "    x1 = [0, 2, 4, 7, 9, 11]\n",
    "    x2 = [0.5, 2.5, 4.5, 7.5, 9.5, 11.5]\n",
    "    x = []\n",
    "    for e in x1:\n",
    "        x.append(e)\n",
    "    for e in x2:\n",
    "        x.append(e)\n",
    "    x.sort()\n",
    "\n",
    "    # Plot graph\n",
    "    plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "    plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "    plt.ylabel(\"Latency (us)\", fontsize=fs)\n",
    "    plt.yticks(np.arange(0, 14, 2))\n",
    "    plt.ylim(0, y_max)\n",
    "    plt.rcParams[\"hatch.linewidth\"] = 2.5\n",
    "    plt.xticks([0.25, 2.25, 4.25, 7.25, 9.25, 11.25],\n",
    "               ['256', '1024\\nsearch', '4096', '256', '1024\\nfind', '4096'])\n",
    "\n",
    "    barlist = plt.bar(x1, soft, width= 0.5, fill=False, label='SOFT')\n",
    "    setHatch_none(barlist, 'tab:gray')\n",
    "\n",
    "    barlist = plt.bar(x2, tlog, width= 0.5, fill=False, label='TLog')\n",
    "    setHatch_index(barlist, 'teal')\n",
    "\n",
    "    # plot again to make edges of bar black\n",
    "    plt.bar(x, temp, color='none', width= 0.5, edgecolor='k')\n",
    "\n",
    "    plt.legend(loc=\"upper left\", frameon=False, fontsize=fs, handleheight=1.3, handletextpad=0.5)\n",
    "\n",
    "    if fileName == \"\":\n",
    "        plt.show()\n",
    "    else:\n",
    "        plt.savefig(saveGraphDir + fileName + \".pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lock-free Linkedlist Latency for Search and Find - 50% updates\n",
    "#opr_lat_update(wb.sheet_by_index(1), 39, 12)\n",
    "opr_lat_update(wb.sheet_by_index(1), 39, 12, \"ll_lat_50\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Lock-free Linkedlist Latency for Search and Find - 5% updates\n",
    "#opr_lat_update(wb.sheet_by_index(1), 45, 10)\n",
    "opr_lat_update(wb.sheet_by_index(1), 45, 10, \"ll_lat_5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Local NUMA Sequential IO b/w in MiB/s with fio sync engine - I2\n",
    "file_name = \"../Data/pmem-idiosyncrasies.xlsx\"\n",
    "wb = xlrd.open_workbook(file_name) \n",
    "sheet = wb.sheet_by_index(1) # Sheet I1\n",
    "\n",
    "# Collect data from sheet\n",
    "io_size=[]\n",
    "read=[]\n",
    "write=[]\n",
    "i=3\n",
    "while i < sheet.ncols:\n",
    "    io_size.append(int(sheet.cell_value(12,i)))\n",
    "    read.append(sheet.cell_value(13,i)/1024)\n",
    "    write.append(sheet.cell_value(14,i)/1024)\n",
    "    i+= 1\n",
    "x = [1,2,3,4,5,6,7]    # X-axis\n",
    "\n",
    "#Plot\n",
    "plt.ylabel(\"Bandwidth (GB/s)\", fontsize=fs)\n",
    "plt.xlabel(\"IO Size (KB)\", fontsize=fs)\n",
    "plt.xticks(x,io_size)\n",
    "plt.yticks(np.arange(0, max(read)+0.2, 0.5))\n",
    "plt.ylim(0, 2.5)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.plot(x, read, 's-c', linewidth=4.0, markersize=ms, label=\"read\")\n",
    "plt.plot(x, write, 'x-y', linewidth=4.0, markersize=ms, label=\"write\")\n",
    "plt.grid(color='grey', linewidth=0.7, linestyle=':')\n",
    "plt.legend(loc='upper left', frameon=False, fontsize=fs)\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"i2_flash.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Flash streaming remote NUMA b/w at 16 threads in MiB/s with fio sync engine - I6\n",
    "sheet = wb.sheet_by_index(5) # Sheet I6\n",
    "\n",
    "# Collect data from sheet\n",
    "io_size=[]\n",
    "seqR=[]\n",
    "randR=[]\n",
    "i=1\n",
    "while i < sheet.ncols:\n",
    "    io_size.append(int(sheet.cell_value(14,i)))\n",
    "    seqR.append(sheet.cell_value(15,i)/1024)\n",
    "    randR.append(sheet.cell_value(16,i)/1024)\n",
    "    i+= 1\n",
    "x = [1,2,3,4,5,6,7]    # X-axis\n",
    "\n",
    "#Plot\n",
    "plt.ylabel(\"Bandwidth (GB/s)\", fontsize=fs)\n",
    "plt.xlabel(\"IO Size (KB)\", fontsize=fs)\n",
    "plt.xticks(x,io_size)\n",
    "plt.yticks(np.arange(0, max(read)+0.2, 0.5))\n",
    "plt.ylim(0, 2.5)\n",
    "plt.rcParams[\"figure.figsize\"] = figSize\n",
    "plt.rc('xtick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.rc('ytick', labelsize=fs)    # fontsize of the tick labels\n",
    "plt.plot(x, seqR, 's-', color='orange', linewidth=4.0, markersize=ms, label=\"Flash Seq\")\n",
    "plt.plot(x, randR, 'x-b', linewidth=4.0, markersize=ms, label=\"Flash Rand\")\n",
    "plt.grid(color='grey', linewidth=0.7, linestyle=':')\n",
    "plt.legend(loc='upper left', frameon=False, fontsize=fs)\n",
    "#plt.show()\n",
    "plt.savefig(saveGraphDir + \"i6_flash_bw.pdf\", bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
